﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.IO;
using System.Configuration;
using System.Web;
using System.Web.UI;
using System.Web.Caching;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

using MyLibrary.Data.SqlServer;
using MyLibrary.Data.Builder;
using MyLibrary.Data.Builder.Config;

namespace MyLibrary.Data.Builder.Component
{
    /// <summary>
    /// 条件组件的基础类
    /// </summary>
    abstract class ConditionComponentBase
    {
        public abstract string DBConnectionKey { get; set; }
        public abstract ReportCondition ReportCondition { get; set; }
        public abstract void DrawASPComponent(PlaceHolder holder);
        public abstract string DrawHTMLComponent();

        /// <summary>
        /// 从数据库中获取源数据
        /// </summary>
        /// <param name="dbKey">数据库连接字符串</param>
        /// <param name="queryString"></param>
        /// <returns></returns>
        protected virtual Dictionary<string, string> GetSourceFromDb(string dbKey, string queryString)
        {
            if (String.IsNullOrEmpty(queryString)) throw new ArgumentException ("查询语句不能为空");
            string dbConnString = GetDbConnectionString(dbKey);
            if (String.IsNullOrEmpty(dbConnString)) throw new NullReferenceException("指定的数据库连接串键不存在");
            Dictionary<string, string> srcData = new Dictionary<string, string>();
            
            try
            {
                DataTable table = SQLServerHelper.ExecuteDataset(dbConnString, CommandType.Text, queryString).Tables[0];
                foreach (DataRow row in table.Rows)
                    srcData.Add(row[0].ToString(), row[1].ToString());
                return srcData;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private string GetDbConnectionString(string dbKey)
        {
            ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings[dbKey];
            if (settings == null)
                return String.Empty;
            else
                return settings.ConnectionString;
        }
    }

    /// <summary>
    /// 组合条件
    /// </summary>
    public class CompositeCondition
    {
        private ConditionList _conditions = null;
        private ComponentType _cmpType = ComponentType.ASPX;
        private string _dbConnKey = String.Empty;
        /// <summary>
        /// 组件类型
        /// </summary>
        public ComponentType ComponentType
        {
            get { return _cmpType; }
            set { _cmpType = value; }
        }
        private object _holder = null;
        /// <summary>
        /// 容器
        /// </summary>
        public object Holder
        {
            get { return _holder; }
            set { _holder = value; }
        }

        /// <summary>
        /// 空构造函数
        /// </summary>
        protected CompositeCondition()
        {
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="config">报表配置</param>
        public CompositeCondition(ReportConfig config)
        {
            _conditions = config.StatConditionList.Conditions;
            _dbConnKey = config.DbConnKey;
        }

        /// <summary>
        /// 添加条件
        /// </summary>
        /// <param name="holder">条件容器</param>
        public void AddCondition()
        {
            //判断是否是从模板中加载条件容器
            foreach (ReportCondition condition in _conditions)
            {
                //如果存在从模板中载入的配置
                if (condition.ConditionSource == "templete")
                {
                    if (String.IsNullOrEmpty(condition.ConditionContent)) throw new ArgumentNullException("模板路径不能为空");
                    LoadConditionFromTemplete(condition.ConditionContent);
                    return;
                }
            }

            if (this._cmpType == ComponentType.ASPX)
                AddAspCondition();
            else if (this._cmpType == ComponentType.HTML)
                AddHTMLCondition();
        }

        /// <summary>
        /// 添加AspX控件
        /// </summary>
        private void AddAspCondition()
        {
            ConditionComponentBase conditionAdder = null;
            foreach (ReportCondition condition in _conditions)
            {
                if (condition.ConditionType == "dropdown")
                    conditionAdder = new ConditionDropDown();
                else if (condition.ConditionType == "datetime")
                    conditionAdder = new ConditionDateTime();
                else if (condition.ConditionType == "normal")
                    conditionAdder = new ConditionNormal();
                else
                    continue;

                conditionAdder.DBConnectionKey = _dbConnKey;
                conditionAdder.ReportCondition = condition;
                conditionAdder.DrawASPComponent((PlaceHolder)_holder);
            }
        }

        /// <summary>
        /// 添加HTML控件
        /// </summary>
        private void AddHTMLCondition()
        {
            StringBuilder builder = new StringBuilder();

            ConditionComponentBase conditionAdder = null;
            foreach (ReportCondition condition in _conditions)
            {
                if (condition.ConditionType == "dropdown")
                    conditionAdder = new ConditionDropDown();
                else if (condition.ConditionType == "datetime")
                    conditionAdder = new ConditionDateTime();
                else if (condition.ConditionType == "normal")
                    conditionAdder = new ConditionNormal();
                else
                    continue;

                conditionAdder.DBConnectionKey = _dbConnKey;
                conditionAdder.ReportCondition = condition;
                builder.Append(conditionAdder.DrawHTMLComponent());
            }
            ((HtmlGenericControl)_holder).InnerHtml = builder.ToString();
        }

        /// <summary>
        /// 从配置模板中读取条件
        /// </summary>
        /// <param name="templePath"></param>
        private void LoadConditionFromTemplete(string templePath)
        {
            StatConditions conditons = null;
            //得到模板的全目录
            if (HttpContext.Current.Cache[templePath] != null)
                conditons = HttpContext.Current.Cache[templePath] as StatConditions;
            else
            {
                string fullPath = HttpContext.Current.Request.MapPath(templePath);
                conditons = StatConditions.LoadConfig(fullPath);
                HttpContext.Current.Cache.Add(templePath, (object)conditons, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, 20, 0), CacheItemPriority.Default, null);
            }
            _conditions = conditons.Conditions;
            if (this._cmpType == ComponentType.ASPX)
                AddAspCondition();
            else if (this._cmpType == ComponentType.HTML)
                AddHTMLCondition();
        }
    }
}
